/*
 * 代号：凤凰
 * http://www.jphenix.org
 * 2014-06-13
 * V4.0
 */
package com.jphenix.webserver.instancea;

import com.jphenix.standard.docs.ClassInfo;

import java.util.*;

/**
 * 线程管理器
 * 
 * 2019-09-17 整理了代码格式
 * 
 * @author 刘虻
 * 2008-8-13下午02:30:57
 */
@ClassInfo({"2019-09-17 10:40","线程管理器"})
public class ThreadManager {

	/**
	 * 默认最大线程数
	 */
	private static final int DEF_MAX_POOLED_THREAD = 20;

	/**
	 * 线程名称
	 */
	protected static final String ID = "instanceb.ThreadManager";

	/**
	 * 超出额定线程名称
	 */
	public  static final String MAXNOTHREAD = ID + ".maxpooledthreads";

	private List<PooledThread>             freeThreads   = null; //空闲线程序列
	private Map<PooledThread,PooledThread> busyThreads   = null; //执行中线程序列
	private int                            maxThreads    = 0;    //最大线程数
	private ThreadFactory                  threadFactory = null; //线程工厂
	
	/**
	 * 构造函数
	 * 2008-8-13下午02:30:57
	 */
	public ThreadManager() {
		super();
	}


	/**
	 * 执行初始化
	 * @author 刘虻
	 * 2008-8-13下午02:46:27
	 */
	public void start() {
		freeThreads = new ArrayList<PooledThread>(getMaxThreadCount());
		busyThreads = new HashMap<PooledThread,PooledThread>(getMaxThreadCount());
	}

	
	/**
	 * 设置线程工厂类
	 * @author 刘虻
	 * 2008-8-13下午02:48:14
	 * @param threadFactory 线程工厂类
	 */
	public void setThreadFactory(ThreadFactory threadFactory) {
		this.threadFactory = threadFactory;
	}
	
	/**
	 * 获取线程工厂类
	 * @author 刘虻
	 * 2008-8-13下午02:48:24
	 * @return 线程工厂类
	 */
	public ThreadFactory getThreadFactory() {
		if (threadFactory==null) {
			threadFactory = new ThreadFactory();
		}
		return threadFactory;
	}
	
	/**
	 * 获取空闲线程序列
	 * @author 刘虻
	 * 2008-8-13下午03:07:56
	 * @return 空闲线程序列
	 */
	public List<PooledThread> getFreeThreadList() {
		if (freeThreads==null) {
			freeThreads = new ArrayList<PooledThread>();
		}
		return freeThreads;
	}

	/**
	 * 获取工作中线程容器
	 * @author 刘虻
	 * 2008-8-13下午03:06:35
	 * @return 工作中线程容器
	 */
	public Map<PooledThread,PooledThread> getBusyThreadMap() {
		if (busyThreads==null) {
			busyThreads = new HashMap<PooledThread,PooledThread>();
		}
		return busyThreads;
	}

	/**
	 * 执行线程
	 * @author 刘虻
	 * 2008-8-13下午02:58:23
	 * @param runnable 核心类
	 */
	public void executeThread(Runnable runnable) {
		PooledThread pt = null;
		do {
			synchronized (freeThreads) {
				if (freeThreads.size() > 0) {
					pt = freeThreads.remove(0);
				}
			}
			if (pt!=null && pt.isAlive()==false) {
				pt = null;
			}
			if (pt == null) {
                synchronized (busyThreads) {
                    if (busyThreads.size() < maxThreads || maxThreads == 0) {
                        pt = new PooledThread();
                        pt.setThreadManager(this);
                        pt.init(); //执行初始化
                    }
                }
            }
			if (pt == null) {
                synchronized (freeThreads) {
                    try {
                        freeThreads.wait();
                    } catch (InterruptedException ie) {}
                }
            }
		} while (pt == null);
		
		pt.setName(ID + "-PooledThread: " + runnable);
		pt.setRunner(runnable);
		
		synchronized (busyThreads) {
			busyThreads.put(pt, pt);
		}
	}

	/**
	 * 覆盖方法
	 * @author 刘虻
	 * 2008-8-13下午03:13:27
	 */
	@Override
    protected void finalize() throws Throwable {
		synchronized (freeThreads) {
			Iterator<PooledThread> i = freeThreads.iterator();
			while (i.hasNext()) {
                i.next().interrupt();
            }
		}
		synchronized (busyThreads) {
			Iterator<PooledThread> i = freeThreads.iterator();
			while (i.hasNext()) {
			    i.next().interrupt();
			}
		}
		super.finalize();
	}

	/**
	 * 覆盖方法
	 * @author 刘虻
	 * 2008-8-13下午03:13:39
	 */
	@Override
    public String toString() {
		if (freeThreads != null && busyThreads != null) {
			return ID + ": free threads " + freeThreads.size() + " busy threads " + busyThreads.size();
		}else {
			return ID + ": not initialized yet. " + super.toString();
		}
	}


	/**
	 * 覆盖方法
	 * @author 刘虻
	 * 2008-8-13下午03:14:04
	 */
	public void addThreadElement(
			Thread element, long timeOut) throws Exception {}


	/**
	 * 覆盖方法
	 * @author 刘虻
	 * 2008-8-13下午03:14:12
	 */
	public void addThreadElement(Thread element) throws Exception {}


	/**
	 * 覆盖方法
	 * @author 刘虻
	 * 2008-8-13下午03:14:16
	 */
	public long getDefaultTimeOut() {
		return 0;
	}


	/**
	 * 覆盖方法
	 * @author 刘虻
	 * 2008-8-13下午02:50:47
	 */
	public int getMaxThreadCount() {
		if (maxThreads<2) {
			maxThreads = DEF_MAX_POOLED_THREAD;
		}
		return maxThreads;
	}


	/**
	 * 覆盖方法
	 * @author 刘虻
	 * 2008-8-13下午03:14:25
	 */
	public long getOverflowWaitTime() {
		return 0;
	}

	/**
	 * 覆盖方法
	 * @author 刘虻
	 * 2008-8-13下午03:14:28
	 */
	public int getThreadCount() {
		return 0;
	}


	/**
	 * 覆盖方法
	 * @author 刘虻
	 * 2008-8-13下午03:14:32
	 */
	public List<?> getThreadVOList() {
		return null;
	}


	/**
	 * 覆盖方法
	 * @author 刘虻
	 * 2008-8-13下午02:54:31
	 */
	public void setDefaultTimeOut(long defaultTimeOut) {}

	/**
	 * 覆盖方法
	 * @author 刘虻
	 * 2008-8-13下午02:51:08
	 */
	public void setMaxThreadCount(int maxThreadCount) {
		if (maxThreadCount<2) {
			return;
		}
		maxThreads = maxThreadCount;
	}


	/**
	 * 覆盖方法
	 * @author 刘虻
	 * 2008-8-13下午02:51:14
	 */
	public void setOverflowWaitTime(long overflowWaitTime) {}


	/**
	 * 覆盖方法
	 * @author 刘虻
	 * 2008-8-13下午02:51:21
	 */
	public void stop() {
		try {
			finalize();
		}catch(Throwable e) {}
	}
}
